home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 138 / 138.xpi / chrome / stumbleupon.jar / content / migrate.js < prev    next >
Text File  |  2010-01-22  |  22KB  |  889 lines

  1.  
  2. function su_migrate_version()
  3. {
  4.     var had_version = su_ds.isPrefDefined("@client_version");
  5.     var prev_version = su_ds.getPrefValue("@client_version", su_useragent);
  6.     if (had_version && (prev_version == su_useragent))
  7.         return;
  8.     su_ds.setValue("@client_version", su_useragent);
  9.     
  10.     // After upgrading, this routine gets run once.  For a new migration
  11.     // routine:
  12.     // 1: Create a M_[identifier] constant using the next sequential bit
  13.     // 2: OR that bit with the others in the 'if (su_new_install)' block
  14.     // 3: Add the migration routine near the bottom, as indicated by the
  15.     //    comment there.
  16.     // 4: Gate the migration routine using the bit.
  17.     // 5: Be sure to OR the bit at the end of the migration routine.
  18.  
  19.     const M_PASSWORDS = 0x1;
  20.     const M_IDS = 0x2;
  21.     const M_POSITION = 0x4;
  22.     const M_PREFS_DB = 0x8;
  23.     const M_V3_27 = 0x10;
  24.     
  25.     if (su_new_install)
  26.     {
  27.         su_ds.setValue("@client_migration_state", M_PASSWORDS | 
  28.                     M_IDS | M_POSITION | M_PREFS_DB | M_V3_27);
  29.         su_ds.flushPrefs();
  30.         return;
  31.     }
  32.  
  33.     su_new_upgrade = true;
  34.     su_prev_version = prev_version;
  35.     su_ds.setValue("@report_error_count", 0);
  36.     su_ds.setValue("@report_error_count_max", 3);
  37.     if (! su_ds.isPrefDefined("@dd_display_message"))
  38.         su_ds.setValue("@dd_display_message", false);
  39.     
  40.     var migration_bitfield = su_ds.getValue("@client_migration_state");
  41.  
  42.     try {  // migration can be tricky, so we do a try
  43.  
  44.     
  45.     if (! (migration_bitfield & M_PASSWORDS))
  46.     {
  47.         // Clear passwords left by old versions.
  48.         su_migrate_clear_old_passwords();
  49.         migration_bitfield |= M_PASSWORDS;
  50.     }
  51.  
  52.     if (! (migration_bitfield & M_IDS))
  53.     {
  54.         // Fix a bug in version 2.81.
  55.         if ((su_ds.getPrefType("stumble.ids") == "Bool") && (stumbleid != 0))
  56.             su_ds.setValue("@id_list", stumbleid + ":");
  57.         else if (su_ds.getPrefType("stumble.ids") == "Char")
  58.             su_ds.setValue("@id_list", su_ds.getValue("stumble.ids"));
  59.  
  60.         su_ds.clearPref("stumble.ids");
  61.         migration_bitfield |= M_IDS;
  62.     }
  63.  
  64.     if (! (migration_bitfield & M_POSITION))
  65.     {
  66.         // Clear passwords left by old versions.
  67.         su_migrate_toolbar_position_scheduled = true;
  68.         migration_bitfield |= M_POSITION;
  69.     }
  70.  
  71.     if (! (migration_bitfield & M_PREFS_DB))
  72.     {
  73.         // version 3.05
  74.         try {
  75.             su_migrate_contacts_to_prefs();
  76.         }
  77.         catch (e) {
  78.             setTimeout(su_migrate_contacts_to_prefs_delayed, 8000);
  79.         }
  80.         migration_bitfield |= M_PREFS_DB;
  81.     }
  82.     
  83.     if (! (migration_bitfield & M_V3_27))
  84.     {
  85.         su_ds.setValue("@enable_db_backup", false);
  86.         
  87.         migration_bitfield |= M_V3_27;
  88.     }
  89.     
  90.     // Add each new version migration routine immediately above.
  91.  
  92.     } catch (e) { try { su_log_error("MIGRATE VERSION", e); } catch (ee) {} }
  93.  
  94.     su_ds.setValue("@client_migration_state", migration_bitfield)
  95.     su_ds.flushPrefs();
  96. }
  97.  
  98. // used during init to handle version-specific migration
  99. function su_migrate_profile(new_profile)
  100. {
  101.     setTimeout(su_migrate_places, 0);
  102.     
  103.     var had_version = su_ds.isPrefDefined("$version");
  104.     var prev_version = su_ds.getPrefValue("$version", su_useragent);
  105.     if (had_version && (prev_version == su_useragent))
  106.         return;
  107.     su_ds.setValue("$version", su_useragent);
  108.  
  109.     // After upgrading, this routine gets run once for each profile,
  110.     // upon the first use of that profile.  For a new migration routine:
  111.     // 1: Create a M_[identifier] constant using the next sequential bit
  112.     // 2: OR that bit with the others in the 'if (su_new_install)' block
  113.     // 3: Add the migration routine near the bottom, as indicated by the
  114.     //    comment there.
  115.     // 4: Gate the migration routine using the bit.
  116.     // 5: Be sure to OR the bit at the end of the migration routine.
  117.  
  118.     // note: maximum positive bit for pref storage is 0x40000000
  119.     const M_USERAGENT = 0x1;
  120.     const M_SHORTCUTS = 0x2;
  121.     const M_MENU_DEPTH_25 = 0x4;
  122.     const M_INTRO_COUNT = 0x8;
  123.     const M_JSON_CONTACTS_AND_MENU_DEPTH_16 = 0x10;
  124.     const M_HIDE_TAG = 0x20;
  125.     const M_FIX_JSON_CONTACTS = 0x40;
  126.     const M_REFRESH_AVATARS = 0x80;
  127.     const M_INIT_AND_MERGE_BUTTONS = 0x100;
  128.     const M_V3_11 = 0x200;
  129.     const M_V3_15 = 0x400; // 0x400:1024 0x7FF:2047
  130.     const M_V3_16 = 0x800;
  131.     const M_V3_17 = 0x1000;
  132.     const M_V3_22 = 0x2000;
  133.     const M_V3_27 = 0x4000;
  134.     const M_V3_27A = 0x8000;
  135.     const M_V3_27B = 0x10000;
  136.     const M_V3_41  = 0x20000;
  137.     const M_V3_41B = 0x40000;
  138.     const M_V3_51  = 0x80000;
  139.     const M_V3_51B = 0x100000;
  140.     const M_V3_63  = 0x200000;
  141.     
  142.     if (su_new_install || new_profile)
  143.     {
  144.         su_ds.setValue("$migration_state", M_USERAGENT | M_SHORTCUTS | 
  145.                     M_MENU_DEPTH_25 | M_INTRO_COUNT | 
  146.                     M_JSON_CONTACTS_AND_MENU_DEPTH_16 | M_HIDE_TAG |
  147.                     M_FIX_JSON_CONTACTS | M_REFRESH_AVATARS | 
  148.                     M_INIT_AND_MERGE_BUTTONS | M_V3_11 | M_V3_15 | M_V3_16 |
  149.                     M_V3_17 | M_V3_22 | M_V3_27 | M_V3_27A | M_V3_27B |
  150.                     M_V3_41 | M_V3_41B | M_V3_51 | M_V3_51B | M_V3_63);
  151.         su_ds.flushPrefs();
  152.         return;
  153.     }
  154.  
  155.     var migration_bitfield = su_ds.getValue("$migration_state");
  156.     
  157.     try {  // migration can be tricky, so we do a try
  158.  
  159.     
  160.     if (! (migration_bitfield & M_USERAGENT))
  161.     {
  162.         // Reset the useragent of pre-1.9996 clients.
  163.         if (su_ds.isPrefDefined("general.useragent.vendorSub") &&
  164.                     (su_ds.getValue("general.useragent.vendorSub").indexOf("StumbleUpon") != -1))
  165.             su_ds.clearPref("general.useragent.vendorSub");
  166.         migration_bitfield |= M_USERAGENT;
  167.     }
  168.     
  169.     if (! (migration_bitfield & M_SHORTCUTS))
  170.     {
  171.         // version <=2.7
  172.         if (su_host.win)
  173.             su_migrate_shortcuts();
  174.         migration_bitfield |= M_SHORTCUTS;
  175.     }
  176.  
  177.     if (! (migration_bitfield & M_MENU_DEPTH_25))
  178.     {
  179.         // version 2.84
  180.         su_ds.setValue("$sendtos_menu_depth", 25);
  181.         migration_bitfield |= M_MENU_DEPTH_25;
  182.     }
  183.  
  184.     if (! (migration_bitfield & M_INTRO_COUNT))
  185.     {
  186.         // version 2.87
  187.         su_ds.setValue("$intro_count", 15);
  188.         migration_bitfield |= M_INTRO_COUNT;
  189.     }
  190.     
  191.     if (! (migration_bitfield & M_JSON_CONTACTS_AND_MENU_DEPTH_16))
  192.     {
  193.         // version 2.90
  194.         su_ds.migrateToContacts();
  195.         su_ds.setValue("$sendtos_menu_depth", 16);
  196.         su_ds.flushPrefs();
  197.         migration_bitfield |= M_JSON_CONTACTS_AND_MENU_DEPTH_16;
  198.     }
  199.  
  200.     if (! (migration_bitfield & M_HIDE_TAG))
  201.     {
  202.         su_ds.setValue("$show_tag", false);
  203.         migration_bitfield |= M_HIDE_TAG;
  204.     }
  205.     
  206.     if (! (migration_bitfield & M_FIX_JSON_CONTACTS))
  207.     {
  208. //        su_ds.fixJSONContacts(false);
  209.         migration_bitfield |= M_FIX_JSON_CONTACTS;
  210.     }
  211.  
  212.     if (! (migration_bitfield & M_REFRESH_AVATARS))
  213.     {
  214.         su_ds.setValue("$has_avatars", false);
  215.         migration_bitfield |= M_REFRESH_AVATARS;
  216.     }
  217.     
  218.     if (! (migration_bitfield & M_INIT_AND_MERGE_BUTTONS))
  219.     {
  220.         // version 3.07 / 3.08
  221.         su_ds.setValue("$show_groups", su_ds.getValue("$show_groups") || 
  222.                     su_ds.getValue("$show_forums"));
  223.         su_ds.setValue("$show_aboutme", su_ds.getValue("$show_aboutme") ||
  224.                     su_ds.getValue("$show_mystumblers"));
  225.  
  226.         su_ds.setValue("$shown_find_friends", true);
  227.         
  228.         migration_bitfield |= M_INIT_AND_MERGE_BUTTONS;
  229.     }
  230.     
  231.     if (! (migration_bitfield & M_V3_11))
  232.     {
  233.         // version 3.11
  234.         if (su_host.dist)
  235.             su_ds.setValue("$show_mode_wiki", true);
  236.         
  237.         var show_searchlinks = su_ds.getValue("$show_searchlinks"); 
  238.         su_ds.setValue("$show_searchlinks_score", show_searchlinks);
  239.         su_ds.setValue("$show_searchlinks_friends", show_searchlinks);
  240.         su_ds.setValue("$show_searchlinks_topic", show_searchlinks);
  241.         su_ds.setValue("$shown_searchlinks", show_searchlinks);
  242.         su_ds.setValue("$show_searchlinks_logo", su_ds.getValue("$searchlink_logos"));
  243.         // pitch social searchlinks to people who have searchlinks disabled
  244.         
  245.         su_ds.setValue("$autocomplete_type", "tag,query");
  246.         
  247.         su_ds.setValue("$show_flag", su_ds.getValue("$show_tag"));
  248.         
  249.         su_get_state(true);
  250.         
  251.         if (su_ds.isPrefDefined("$stumblestats") &&
  252.                     (su_ds.getValue("$stumblestats") != ""))
  253.         {
  254.             var stumblestats = su_ds.getValue("$stumblestats");
  255.     
  256.             var stumbletypes = "";
  257.             var stumblereferrals = "";
  258.             var first = 0;
  259.             var splitseen = stumblestats.split(".");
  260.             var i;
  261.             for (i = 0; i < splitseen.length; i++)
  262.             {
  263.                 if (first == 0)
  264.                 {
  265.                     first = 1;
  266.                 }
  267.                 else
  268.                 {
  269.                     stumbletypes += ".";
  270.                     stumblereferrals += ".";
  271.                 }
  272.                 stumbletypes += "0";
  273.             }
  274.             
  275.             // most profiles were migrated when this was in load_data1()
  276.             if (! su_ds.isPrefDefined("$stumbletypes"))
  277.                 su_ds.setValue("$stumbletypes", stumbletypes);
  278.             
  279.             su_ds.setValue("$stumblereferrals", stumblereferrals);
  280.         }
  281.         
  282.         su_check_dyn_channels();
  283.         
  284.         migration_bitfield |= M_V3_11;
  285.     }
  286.  
  287.     if (! (migration_bitfield & M_V3_15))
  288.     {
  289.         // version 3.15
  290.         
  291.         su_ds.enableFeature("$sociallinks");
  292.         
  293.         // remove ancient legacy contacts
  294.         var contacts = su_ds.getValue("$contacts");
  295.         var i;
  296.         for (i = 0; i < contacts.length; i++)
  297.         {
  298.             var contact = contacts[i];
  299.             if (contact.nickname && (! contact.contactid) &&
  300.                         (typeof(contact.fbid) == "undefined"))
  301.                 su_ds.deleteRow(contact);
  302.         }
  303.         
  304.         migration_bitfield |= M_V3_15;
  305.     }
  306.         
  307.     if (! (migration_bitfield & M_V3_16))
  308.     {
  309.         var tmpstr = su_ds.getValue("$process_rarely_timestamp");
  310.         if (tmpstr == "")
  311.             su_ds.setValue("$process_rarely_timestamp", "0");
  312.         
  313.         su_check_dyn_channels();
  314.         
  315.         migration_bitfield |= M_V3_16;
  316.     }
  317.  
  318.     if (! (migration_bitfield & M_V3_17))
  319.     {
  320. //        if (su_ds.getValue("$shown_find_friends_time_s") == 0)
  321. //            su_ds.setValue("$shown_find_friends_time_s", 2);
  322.         su_ds.setValue("$show_tag", false);
  323.         su_ds.setValue("$show_flag", false);
  324.         su_get_state(true);
  325.         clear_stumbles();
  326.         migration_bitfield |= M_V3_17;
  327.     }
  328.  
  329.     if (! (migration_bitfield & M_V3_22))
  330.     {
  331.         su_migrate_check_shared();
  332.         if (su_ds.isPrefDefined("$referral_count"))
  333.         {
  334.             su_ds.setValue("$undelivered_count", parseInt(su_ds.getValue("$referral_count")));
  335.             su_ds.clearPref("$referral_count");
  336.         }
  337.         
  338.         su_get_state(true);
  339.  
  340.         migration_bitfield |= M_V3_22;
  341.     }
  342.     
  343.     if ((! (migration_bitfield & M_V3_27A))
  344.             || (! (migration_bitfield & M_V3_27B)))
  345.     {
  346.         su_ds.setValue("$show_legacy_network", false);    
  347.         
  348.         su_ds.setValue("$migrate_places_state", "a");
  349.         
  350.         migration_bitfield |= M_V3_27A;
  351.         migration_bitfield |= M_V3_27B;
  352.     }
  353.     
  354.     if (! (migration_bitfield & M_V3_41))
  355.     {
  356.         // Turn the comment icon off by default.
  357.         su_ds.setValue("$show_searchlinks_comment_icon", false);
  358.         migration_bitfield |= M_V3_41;
  359.     }
  360.     
  361.     if (! (migration_bitfield & M_V3_41B))
  362.     {
  363.         // No longer add ourselves to the noscript whitelist and XSS 
  364.         // exception list by default.
  365.         su_ds.setValue("@whitelist_upon_load", false);
  366.         migration_bitfield |= M_V3_41B;
  367.         
  368.         // For existing users we treat the "user_changed" values as true
  369.         // so we don't change preferences that they may have set explicitly.
  370.         su_ds.setValue("$show_info_user_changed", true);
  371.         su_ds.setValue("$show_referral_user_changed", true);
  372.         su_ds.setValue("$show_home_user_changed", true);
  373.         su_ds.setValue("$show_friends_user_changed", true);
  374.     }
  375.  
  376.     if (! (migration_bitfield & M_V3_51))
  377.     {
  378.         // Turn the search links topic off by default, even for existing users.
  379.         su_ds.setValue("$show_searchlinks_topic", false);
  380.         migration_bitfield |= M_V3_51;
  381.     }
  382.     
  383.     if (! (migration_bitfield & M_V3_51B))
  384.     {
  385.         // If they haven't changed the old default channel button configuration
  386.         // then remove the channel buttons
  387.         var modesChanged = false;
  388.  
  389.         var oldDefaultModes = [ 
  390.             [ "$show_mode_friends", true ],
  391.             [ "$show_mode_more", true ],
  392.             [ "$show_mode_news", true ],
  393.             [ "$show_mode_photo", true ],
  394.             [ "$show_mode_search", false ],
  395.             [ "$show_mode_stumblers", false ],
  396.             [ "$show_mode_video", true ],
  397.             [ "$show_mode_wiki", false ]
  398.         ];
  399.         
  400.         for(var i=0; i<oldDefaultModes.length; i++)
  401.         {
  402.             var entry = oldDefaultModes[i]
  403.             if(su_ds.getValue(entry[0]) != entry[1])
  404.             {
  405.                 modesChanged = true;
  406.                 break;
  407.             }
  408.         }
  409.  
  410.         if(!modesChanged)
  411.         {
  412.             // Check whether they have added any "thru" domain buttons
  413.             var thruChannels = su_ds.getThruDomainChannels();
  414.             for(var i=0; i<thruChannels.length; i++)
  415.             {
  416.                 if(thruChannels[i].show)
  417.                 {
  418.                     modesChanged = true;
  419.                     break;
  420.                 }
  421.             }
  422.         }
  423.         
  424.         // If they haven't changed the old default settings, then remove the
  425.         // channels button section
  426.         if(!modesChanged)
  427.         {
  428.             su_ds.setValue("$show_mode", false);
  429.             // But make sure the channels selector menu is visible
  430.             su_ds.setValue("$show_topics", true);
  431.             
  432.         }
  433.         migration_bitfield |= M_V3_51B;
  434.     }
  435.     
  436.     if (! (migration_bitfield & M_V3_63))
  437.     {
  438.         
  439.         if (su_ds.getValue("$show_legacy_forums")
  440.                 && (! su_ds.getValue("$show_groups")))
  441.         {
  442.             su_ds.setValue("$show_groups", true);
  443.         }
  444.         
  445.         migration_bitfield |= M_V3_63;
  446.     }
  447.  
  448.     // Add each new profile migration routine immediately above.
  449.  
  450.     } catch (e) { try { su_log_error("MIGRATE PROFILE", e); } catch (ee) {}}
  451.     
  452.     su_ds.setValue("$migration_state", migration_bitfield)
  453.     su_ds.flushPrefs();
  454. }
  455.  
  456. function su_migrate_places()
  457. {
  458.     if (! su_host.places)
  459.         return;
  460.     
  461.     var state = su_ds.getValue("$migrate_places_state");
  462.     
  463.     if (state == "d")
  464.         return;
  465.     
  466.     if (su_ds.getValue("#migrating_places"))
  467.         return;
  468.     
  469.     su_ds.setValue("#migrating_places", true);
  470.     
  471.     var context = new Object();
  472.     context.ratings_str = null;
  473.     context.processed_key = null;
  474.     context.processed_idx = null;
  475.     context.state = state;
  476.     context.unrated_rows = null;
  477.     setTimeout(function (win, context) { win.su_migrate_places2(context) }, 0, window, context);
  478. }
  479.  
  480. function su_migrate_places2(context)
  481. {
  482.     var new_state = context.state;
  483.     var migrate_file;
  484.     var db;
  485.     var result;    
  486.     var row;
  487.     var url;
  488.     var urlid;
  489.     var rating;
  490.     var legacy_rating;
  491.     var has_bookmark;
  492.     var has_thumbup_tag;
  493.     var bookmarked;
  494.     var sql;
  495.     var ts;
  496.     var parts;
  497.     var lines;
  498.     var urls;
  499.     var i;
  500.     var j;
  501.     switch (context.state)
  502.     {
  503.         case "a":
  504.             // 1. load ratings and backup places
  505.             context.ratings_str = su_read_file_user("stumblerating");
  506.             su_backup_places("MIGRATEPLACES BACKUP");
  507.             new_state = "b";
  508.             break;
  509.         case "b":
  510.             // 2. backup ratings
  511.             if (! context.ratings_str)
  512.                 context.ratings_str = su_read_file_user("stumblerating");
  513.             migrate_file = su_ds.getResourceNSIFile("temp", "migraterating" + su_ds.userid);
  514.             su_ds.writeFile(migrate_file, context.ratings_str);
  515.             su_ratings = null;
  516.             new_state = "c";
  517.             break;
  518.         case "c":
  519.             // 3. initialize ratings and processed_idx if necessary
  520.             if (! su_ratings)
  521.                 su_load_ratings();
  522.             
  523.             db = su_ds.getDatabase();
  524.             if (! context.processed_key)
  525.                 context.processed_key = su_ds.getValue("$migrate_places_key");
  526.             
  527.             if (! context.url_rows)
  528.             {
  529.                 sql = "SELECT urlid,rating FROM url WHERE urlid>" + db.q(context.processed_key) + " ORDER BY urlid LIMIT 1000";
  530.                 context.url_rows = db.query(sql);
  531.                 context.processed_idx = 0;
  532.             }
  533.             
  534.             // 4. check whether we're done
  535.             if (context.url_rows.length == 0)
  536.             {
  537.                 context.processed_key = "";
  538.                 context.processed_idx = 0;
  539.                 su_ds.setValue("$migrate_places_key", "");                
  540.                 su_ds.setValue("$migrate_places_idx", 0);
  541.                 su_ds.setValue("#migrating_places", false)
  542.                 new_state = "d";
  543.                 setTimeout(su_download_favs, 0, false);
  544.                 setTimeout(su_process_command_queue, 0);
  545.                 break;
  546.             }
  547.             
  548.             rating = context.url_rows[context.processed_idx].rating;
  549.             urlid = context.url_rows[context.processed_idx].urlid;
  550.             
  551.             context.processed_key = urlid;
  552.             
  553.             // 5. save progress periodically
  554.             if ((context.processed_idx % 100) == 0)
  555.             {
  556.                 su_ds.setValue("$migrate_places_key", urlid);
  557.                 su_ds.flushPrefs();
  558.             }
  559.             
  560.             context.processed_idx++;
  561.  
  562.             if (context.url_rows.length == context.processed_idx)
  563.             {
  564.                 context.url_rows = null;
  565.                 context.processed_idx = 0;
  566.             }
  567.             
  568.             // 6. get urls and legacy rating for this urlid
  569.             sql = "SELECT url FROM url_map WHERE urlid=" + db.q(urlid);
  570.             rows = db.query(sql);
  571.             if (rows.length == 0)
  572.                 break; // shouldn't happen
  573.             
  574.             legacy_rating = null;
  575.             urls = new Array();
  576.             while (row = rows.shift())
  577.             {
  578.                 urls.push(row.url);
  579.                 if (((typeof su_ratings[row.url]) != "undefined")
  580.                         && (legacy_rating != 1)) // prefer thumbup over thumbdown
  581.                     legacy_rating = su_ratings[row.url];
  582.             }
  583.             
  584.             ts = su_ds.getTaggingService();
  585.             
  586.             // 7. check existing bookmarks and tags
  587.             has_bookmark = false; 
  588.             has_thumbup_tag = false;
  589.             for (i = 0; i < urls.length; i++)
  590.             {
  591.                 url = urls[i];
  592.                 nsiuri = su_get_nsiuri(url);
  593.                 tags = ts.getTagsForURI(nsiuri, []);
  594.                 bookmarked = su_is_bookmarked(nsiuri);
  595.                 
  596.                 has_bookmark = has_bookmark || bookmarked;
  597.                 for (j = 0; j < tags.length; j++)
  598.                 {
  599.                     if (tags[j] == "SU")
  600.                     {
  601.                         has_thumbup_tag = true;
  602.                         break;
  603.                     }
  604.                 }
  605.                 
  606.                 // 7a. if the url isn't bookmarked, nuke spurious tags
  607.                 if (tags.length && (! bookmarked))
  608.                     ts.untagURI(nsiuri, tags);
  609.             }
  610.             
  611.             // 8. update ratings
  612.             if (has_bookmark && has_thumbup_tag && (rating != 1))
  613.             {
  614.                 // bookmarked with SU tag gets thumbup
  615.                 sql = "UPDATE url SET rating=1 WHERE urlid=" + db.q(urlid); 
  616.                 db.query(sql);
  617.             }
  618.             else if ((legacy_rating != null) && (legacy_rating != rating))
  619.             {
  620.                 // legacy rating overrides db rating
  621.                 sql = "UPDATE url SET rating=" + db.v(legacy_rating) + " WHERE urlid=" + db.q(urlid);
  622.                 db.query(sql);
  623.             }
  624.             else if ((legacy_rating == null) && (rating == 0))
  625.             {
  626.                 // unrate thumbdowns that don't have a legacy_rating
  627.                 sql = "UPDATE url SET rating=-1 WHERE urlid=" + db.q(urlid);
  628.                 db.query(sql);
  629.             }
  630.             
  631.             break;
  632.     }
  633.     
  634.     if (context.state != new_state)
  635.     {
  636.         context.state = new_state;
  637.         su_ds.setValue("$migrate_places_state", new_state);
  638.         su_ds.flushPrefs();
  639.     }
  640.     
  641.     if (new_state != "d")
  642.         setTimeout(function (win, context) { win.su_migrate_places2(context) }, 0, window, context);
  643. }
  644.  
  645. function su_migrate_check_shared()
  646. {
  647.     var contacts = su_ds.getValue("$contacts");
  648.     var share_count = 0;
  649.     var i;
  650.     for (i = 0; i < contacts.length; i++)
  651.     {
  652.         if (contacts[i].referral_count)
  653.             share_count += contacts[i].referral_count;
  654.         
  655.         if (share_count >= 2)
  656.             break;
  657.     }
  658.     
  659.     if (share_count >= 1)
  660.         su_ds.setValue("$poll_state", "f");
  661.     
  662.     if (share_count >= 2)    
  663.         su_ds.setValue("$shown_referral_info", true);
  664. }
  665.  
  666. function su_migrate_contacts_to_prefs_delayed()
  667. {
  668.     try {
  669.         su_migrate_contacts_to_prefs();
  670.     }
  671.     catch (e) {
  672.         su_log_error("MIGRATE CONTACT_DELAYED", e);
  673.         return;
  674.     }
  675.     
  676.     if (stumbleid == 0);
  677.         return;
  678.     
  679.     su_invoke_global_event("refresh-referral-menu", null);
  680. }
  681.  
  682. function su_migrate_contacts_to_prefs()
  683. {
  684.     var file = su_ds.getResourceNSIFile(null, "json_db")
  685.     if (! file.exists())
  686.         return;
  687.     
  688.     var db = su_ds.deserialize(su_ds.readFile(file));
  689.     if (! db)
  690.         return;
  691.     
  692.     var ids = su_ds.getValue("@id_list").split(":");
  693.     var i;
  694.     for (i = 0; i < ids.length; i++)
  695.     {
  696.         if (ids[i] == "")
  697.             continue;
  698.         
  699.         if (! db[ids[i]])
  700.             continue;
  701.         
  702.         if (! db[ids[i]]["contact"])
  703.             continue;
  704.  
  705.  
  706.         var names = su_ds.getPrefNames("stumble." + ids[i] + ".c.");
  707.         if (! names)
  708.             return;
  709.         
  710.         var pref_contacts = new Array();
  711.         var k;
  712.         for (k = 0; k < names.length; k++)
  713.             pref_contacts.push(su_ds.deserialize(su_ds.getValue(names[k])));
  714.  
  715.         
  716.         var contacts = db[ids[i]]["contact"];
  717.         if (! contacts.constructor != Array)
  718.         {
  719.             // convert to array
  720.             var a = new Array();
  721.             var p;
  722.             for (p in contacts)
  723.             {
  724.                 if ((typeof (contacts[p])) == "function")
  725.                     continue;
  726.                 
  727.                 if ((typeof (contacts[p])) == "undefined")                
  728.                     continue;
  729.                 
  730.                 if (contacts[p].constructor == Object)
  731.                     a.push(contacts[p]);
  732.             }
  733.             contacts = a;
  734.         }
  735.         
  736.         var j;
  737.         var contact;
  738.         for (j = 0; j < contacts.length; j++)
  739.         {
  740.             var pref_contact = null;
  741.             if (contacts[j].nickname)
  742.             {
  743.                 pref_contact = su_get_row(
  744.                             pref_contacts,
  745.                             "nickname",
  746.                             contacts[j].nickname);
  747.             }
  748.             else if (contacts[j].email)
  749.             {
  750.                 pref_contact = su_get_row(
  751.                             pref_contacts,
  752.                             "email",
  753.                             contacts[j].email);
  754.             }
  755.             else
  756.             {
  757.                 continue;
  758.             }
  759.             
  760.             if (pref_contact)
  761.             {
  762.                 contacts[j]._r = pref_contact._r;
  763.             }
  764.             else
  765.             {
  766.                 var autoinc_name = "stumble." + ids[i] + ".c_ai";
  767.                 contacts[j]._r = su_ds.getPrefValue(autoinc_name, 0);
  768.                 su_ds.setValue(autoinc_name, (contacts[j]._r + 1));
  769.             }
  770.             contacts[j]._t = "c";
  771.             var name = "stumble." + ids[i] + ".c." + contacts[j]._r;
  772.             su_ds.setValue(name, su_ds.serialize(contacts[j]));
  773.         }
  774.     }
  775. }
  776.  
  777. function su_get_row(rows, col_name, value)
  778. {
  779.     var i;
  780.     for (i = 0; i < rows.length; i++)
  781.     {
  782.         if (rows[i][col_name] && (rows[i][col_name] == value))
  783.             return rows[i];
  784.     }
  785.     return null;
  786. }
  787.  
  788. function su_migrate_clear_old_passwords()
  789. {
  790.     var names =     su_ds.getPrefNames("stumble.");
  791.     var current_id_pref = "stumble." + 
  792.                 su_ds.getValue("@current_user") +
  793.                 ".password";
  794.     var i;
  795.     for (i = 0; i < names.length; i++)
  796.     {
  797.         if (names[i].indexOf("$password") == -1) continue;
  798.         if (names[i] == current_id_pref) continue;
  799.         su_ds.clearPref(names[i]);
  800.     }
  801. }
  802.  
  803. function su_migrate_shortcuts()
  804. {
  805.     // If we're on Windows, and if all of the key bindings match the 
  806.     // old defaults, change the bindings to the new defaults. -- JW
  807.     var details = new Array();
  808.     var o;
  809.     
  810.     o = new Object();
  811.     o.oldpref = "$shortcut-stumble";
  812.     o.newpref = "$shortcut_stumble";
  813.     o.oldval = "Alt+VK_F1";
  814.     o.newval = "Alt+VK_BACK_QUOTE";
  815.     details.push(o);
  816.     
  817.     o = new Object();
  818.     o.oldpref = "$shortcut-thumbup";
  819.     o.newpref = "$shortcut_thumbup";
  820.     o.oldval = "Alt+VK_F2";
  821.     o.newval = "Alt+VK_1";
  822.     details.push(o);        
  823.     
  824.     o = new Object();
  825.     o.oldpref = "$shortcut-thumbdown";
  826.     o.newpref = "$shortcut_thumbdown";
  827.     o.oldval = "Alt+VK_F3";
  828.     o.newval = "Alt+VK_2";
  829.     details.push(o);        
  830.     
  831.     o = new Object();
  832.     o.oldpref = "$shortcut-reviews";
  833.     o.newpref = "$shortcut_reviews";
  834.     o.oldval = "Alt+VK_F5";
  835.     o.newval = "Alt+VK_3";
  836.     details.push(o);        
  837.     
  838.     o = new Object();
  839.     o.oldpref = "$shortcut-toolbar";
  840.     o.newpref = "$shortcut_toolbar";
  841.     o.oldval = "Alt+VK_11";
  842.     o.newval = "Alt+VK_11";
  843.     details.push(o);        
  844.     
  845.     var keybindings_edited = false;
  846.     var i;
  847.     for (i = 0; i < details.length; i++)
  848.     {
  849.         if (su_ds.isPrefDefined(details[i].oldpref))
  850.         {
  851.             keybindings_edited = (su_ds.getValue(details[i].oldpref) != details[i].oldval);
  852.             if (keybindings_edited)
  853.             {
  854.                 break;
  855.             }
  856.         }
  857.     }
  858.     
  859.     if (keybindings_edited)
  860.     {
  861.         su_init_key_const_dictionaries();
  862.  
  863.         for (i = 0; i < details.length; i++)
  864.         {
  865.             // This tranlates keyids like " " and "A" to "VK_SPACE" and 
  866.             // "VK_A". -- JW
  867.             var keyspec = su_ds.getValue(details[i].oldpref);
  868.             var parts = keyspec.split("+");
  869.             var old_keyid;
  870.             if (parts[parts.length - 1] == "")
  871.                 old_keyid = "+";
  872.             else
  873.                 old_keyid = parts[parts.length - 1];
  874.  
  875.             if (old_keyid.length == 1)
  876.             {
  877.                 var new_keyid = su_keyids_by_char[old_keyid];
  878.                 if (new_keyid)
  879.                 {
  880.                     var regexp = new RegExp(su_escape_regexp_chars(old_keyid) + "$");
  881.                     keyspec = keyspec.replace(regexp, new_keyid);
  882.                 }
  883.             }
  884.             su_ds.setValue(details[i].newpref, keyspec);
  885.         }
  886.     }
  887. }
  888.  
  889.